package cc.iteachyou.template.dom;

import cc.iteachyou.template.taglib.IDirectiveHandler;
import cc.iteachyou.template.taglib.directives.*;
import cc.iteachyou.template.taglib.result.DirectiveResult;
import cc.iteachyou.template.utils.VariableHelper;
import lombok.Data;

import java.util.*;

@Data
public class VirtualDOMElementNode extends VirtualDOMNode {
    private List<VirtualDOMAttr> attrs;
    private List<VirtualDOMNode> children;

    private String beginTagPrefixDelimiter = "<";
    private String beginTagSuffixDelimiter = ">";
    private String singleTagSuffixDelimiter = "/>";

    private String endTagPrefixDelimiter = "</";
    private String endTagSuffixDelimiter = ">";

    public String toString(){
        VariableHelper variableHelper = VariableHelper.getInstance();
        Map<String, Object> templateData = variableHelper.get();
        String html = "";
        context = new RendererVirtualDOMAttrContext();
        context.setNode(this);
        if(loopable){
            Object eval = engine.eval(loopArray, templateData);
            if(eval instanceof Integer){
                Integer total = (Integer) eval;
                for (int index = 0; index < total;index++) {
                    templateData.put("index", index);
                    templateData.put(loopItemKey, index);
                    html += build();
                }
            } else if(eval.getClass().isArray()){
                Object[] array = (Object[]) eval;
                for (int index = 0; index < array.length;index++) {
                    templateData.put("index", index);
                    templateData.put(loopItemKey, array[index]);
                    html += build();
                }
            } else if(eval instanceof Collection){
                Collection collection = (Collection) eval;
                Iterator iterator = collection.iterator();
                int index = 0;
                while (iterator.hasNext()){
                    Object next = iterator.next();
                    templateData.put("index", index++);
                    templateData.put(loopItemKey, next);
                    html += build();
                }
            }
            // 回收For item数据
            templateData.remove(loopItemKey);
        } else if(branchable){
            Object eval = engine.eval(branchData, templateData);
            Boolean b = (Boolean) eval;
            templateData.put("dreamer_template_engine_if_result", b);
            if(b){
                html += build();
            }
        } else{
            html += build();
        }
        return html;
    }

    private String build(){
        VariableHelper variableHelper = VariableHelper.getInstance();
        StringBuilder html = new StringBuilder();
        html.append(beginTagPrefixDelimiter);
        html.append(name);
        if(attrs != null && attrs.size() > 0){
            for (int i = 0; i < attrs.size(); i++) {
                VirtualDOMAttr attr = attrs.get(i);
                context.setAttr(attr);
                if (attr.getType() == VirtualDOMAttr.VirtualDOMAttrTypeEnum.NATIVE) {
                    html.append(" ").append(attr.getName()).append("=\"").append(attr.getValue()).append("\"");
                } else if (attr.getType() == VirtualDOMAttr.VirtualDOMAttrTypeEnum.SYSTEM) {// 系统内置指令
                    try {
                        IDirectiveHandler handler = attr.getHandler();
                        Optional<DirectiveResult> optional = handler.handler(context, variableHelper.get());
                        if(!optional.isPresent()){
                            continue;
                        }
                        DirectiveResult result = optional.get();
                        if (handler instanceof AltDirectiveHandler
                                || handler instanceof ClassDirectiveHandler
                                || handler instanceof HrefDirectiveHandler
                                || handler instanceof IdDirectiveHandler
                                || handler instanceof NameDirectiveHandler
                                || handler instanceof SrcDirectiveHandler
                                || handler instanceof TitleDirectiveHandler
                                || handler instanceof ValueDirectiveHandler) {
                            html.append(" ").append(result.getName()).append("=\"").append(result.getValue()).append("\"");
                        } else if (handler instanceof CheckedDirectiveHandler) {// 单选按钮、复选框选中属性
                            Boolean b = (Boolean) result.getValue();
                            if (b) {
                                html.append(" ").append(result.getName()).append("=\"").append("checked").append("\"");
                            }
                        } else if (handler instanceof SelectedDirectiveHandler) {// 下拉选择选中属性
                            Boolean b = (Boolean) result.getValue();
                            if (b) {
                                html.append(" ").append(result.getName()).append("=\"").append("selected").append("\"");
                            }
                        } else if (handler instanceof TextDirectiveHandler) {// text指令直接向标签内添加内容，无需处理

                        } else if (handler instanceof ElseDirectiveHandler) {// text指令直接向标签内添加内容，无需处理

                        } else if (handler instanceof ScriptDirectiveHandler) {
                            context.getData().put(attr.getName(), attr.getValue());
                        }
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                } else if (attr.getType() == VirtualDOMAttr.VirtualDOMAttrTypeEnum.CUSTOM) { // 自定义指令

                }
            }
        }

        if(isSingleTag){
            html.append(" ");
            html.append(singleTagSuffixDelimiter);
        }else {
            html.append(beginTagSuffixDelimiter);
            // 处理孩子
            if (children != null && children.size() > 0) {
                String cascade = cascade();
                html.append(cascade);
            }

            html.append(endTagPrefixDelimiter);
            html.append(name);
            html.append(endTagSuffixDelimiter);
        }
        return html.toString();
    }

    private String cascade(){
        StringBuilder html = new StringBuilder();
        for (VirtualDOMNode child : children) {
            html.append(child.toString());
        }
        return html.toString();
    }
}
